package myservlet.control;
import mybean.data.login;
import java.io.IOException;
import java.io.PrintWriter;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.sql.Timestamp;
import java.util.Iterator;
import java.util.LinkedList;

import javax.servlet.*;
import javax.servlet.http.*;

public class PutGoodToCar extends HttpServlet{
	public void init(ServletConfig config) throws ServletException {
			super.init(config);
			try {//加载驱动
				Class.forName("com.mysql.jdbc.Driver");	
			}
			catch(Exception e) {}
		}
	public  void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		req.setCharacterEncoding("utf-8");
		resp.setContentType("text/html;charset=UTF-8");
		PrintWriter out = resp.getWriter();
		String good = req.getParameter("borrow");//获取用户提交的单车的信息
		System.out.println(good);
		login loginBean =null; 
		HttpSession session= req.getSession(true);
		try {
			loginBean = (login)session.getAttribute("loginBean");
			boolean b=loginBean==null || loginBean.getLogname()==null || loginBean.getLogname().length()==0;
			if(b) {
				out.println("<script language = javascript>alert('请重新登录!');");
				out.println("location.href='index.jsp'</script>");
				return;
			}
			LinkedList<String> car = loginBean.getcar();
			//每个用户只能借一辆车，如果有未还的要先还了才能借						
			//修改单车的状态，改变用户的余额和信用分                                                                                                                                    //允许批量更新
			String url = "jdbc:mysql://127.0.0.1:3306/bike?&useSSL=false&serverTimezone=GMT%2B8&allowMultiQueries=true";
			Connection con = null;
			PreparedStatement sql = null;
			/*  
			 *1,首先把Auto commit设置为false,不让它自动提交  
			 *2,进行手动提交（commit）  
			 *3,提交完成后回复现场将Auto commit,还原为true,  
			 *4,当异常发生执行catch中SQLException时，记得要rollback(回滚)；
			 *
			 * PreparedStatement:  
			 1.addBatch() 将一组参数添加到 PreparedStatement对象内部  
			 2.executeBatch() 将一批参数提交给数据库来执行，如果全部命令执行成功，则返回更新计数组成的数组。    
			 注意：PreparedStatement中使用批量更新时，要先设置好参数后再使用addBatch()方法加入缓存
			 */  
			try {
				// 1. 建立与数据库的连接 
				con = DriverManager.getConnection(url,"root","744615");
				String condition="select * from orderform where username='"+loginBean.getLogname()+"'";
				Statement stm=con.createStatement();
				ResultSet r=stm.executeQuery(condition);//查看订单表里是否有订单
				if(r.next()==true) {
					out.println("<script language = javascript>alert('你还有未还的车，请先还车!');");
					out.println("location.href='return.jsp'</script>");
					stm.close();//关闭
				}
				else{
					car.add(good);//单车信息放入列表中
				Iterator<String> iterator=car.iterator();
				double price=0,deposit=0;
				String id="";//单车价格和状态
				int i=0;
				while(iterator.hasNext()){
					String goods=iterator.next();
					//订单中物品的后缀是“#单车编号$租金#价格数字”，比如”0001租金99价格0.5:  *0001$99#0.5“
					i=goods.lastIndexOf("*");//定位到*
					int index=goods.lastIndexOf("$");
					int index2=goods.lastIndexOf("#");//分离出价格
					if(i!=-1&& index!= -1 && index2!=-1){
						price=Double.parseDouble(goods.substring(index2+1));//分离出价格
						deposit=Double.parseDouble(goods.substring(index+1,index2));//押金
						id=goods.substring(i+1,index);//单车编号						
					}
				}				
				//查询当前用户的余额和信用分				
				condition="select Umoney,Ucredit,Udeposit from user where Nickname='"+loginBean.getLogname()+"'";
				Statement st=con.createStatement();
				con.setAutoCommit(false);
				ResultSet rs=st.executeQuery(condition);
				String money="",credict ="";
				double Udeposit=0;
				while(rs.next()){
					money = rs.getString("Umoney");
					credict = rs.getString("Ucredit");
					Udeposit= Double.parseDouble(rs.getString("Udeposit"));
				}
				if((Double.parseDouble(money) < price) || (Udeposit< deposit)) {
					out.println("<script language = javascript>alert('余额或租金不够，借车失败!请先到个人信息中充值修改');");
					out.println("location.href='byPageShow.jsp'</script>");
					return;
				}
				st.close();
				//根据用户选择的单车修改数据库中的相关表			
				condition="insert into orderform values(?,?,?,?)";//插入到订单表中
				// 2. 执行sql语句   
				// 1).先创建PreparedStatement语句(发送slq请求）：
				sql=con.prepareStatement(condition); 
				//con.setAutoCommit(false);//1、设置为false,不让它自动提交,每次executeUpdate将不会立刻提交,而是等待commit(); 
				// 2) 设置sql语句1  
				sql.setInt(1, 1);//订单序号会自动增加  // 对SQL语句中的第一个参数赋值  
				sql.setString(2, loginBean.getLogname());
				sql.setString(3, good.substring(0,i));	
				sql.setString(4, id);	
				sql.executeUpdate();
				// 关闭PreparedStatement 
				sql.close();
				 // 2) 设置sql语句2--修改单车状态
				condition="update bike set B_memo='已借' where B_id='"+id+"'";
				sql=con.prepareStatement(condition);
				sql.executeUpdate();                  
				sql.close(); //每执行一个语句记得关闭，否则会出现游标错误
				 // 3) 设置sql语句3--修改用户的余额和信用分
				condition="update user set Umoney=?-'"+price+"',Ucredit=?+1 where Nickname=?";
				sql=con.prepareStatement(condition);
				sql.setString(1, money);  
				sql.setString(2, credict);
				sql.setString(3, loginBean.getLogname());
				sql.executeUpdate();  //执行更新操作，  更新数据库 
	            sql.close(); 
	            // 4) 设置sql语句4--修改单车使用记录	           
	            condition="insert into userecord values(?,?,?)";
	            sql=con.prepareStatement(condition);
	            sql.setString(1, id);
				sql.setString(2, loginBean.getLogname());
				sql.setTimestamp(3, new Timestamp(System.currentTimeMillis()));//时间参数
	            sql.executeUpdate();  //执行更新操作，  更新数据库 
	            sql.close(); 
				// 若成功执行完所有的更新操作，则正常结束 
				con.commit();//进行手动提交（commit） 
				con.setAutoCommit(true); //提交完成后回复现场将Auto commit,还原为true
				out.println("<script language = javascript>alert('借车成功，可以到我的订单中查看!');");
				out.println("location.href='borrow.jsp'</script>");
				}
			}
			catch (SQLException exp){
				out.println("<script language = javascript>alert('更新数据库失败，借车失败!');");
				out.println("location.href='byPageShow.jsp'</script>");
				System.out.println(exp);
				try {   
					 // 若出现异常，对数据库中所有已完成的操作全部撤销，则回滚到事务开始状态   
					if(!con.isClosed()){   
					 con.rollback();//4,当异常发生执行catch中SQLException时，记得要rollback(回滚)；   
					 System.out.println("更新数据库失败，回滚！");
					 car.clear();//清空列表
					 con.setAutoCommit(true);   
					 }   
					} 
				 catch (SQLException e1) {   
					 e1.printStackTrace();   
					}
			}
			finally{  
				// 关闭PreparedStatement  
		        sql.close(); 
	            // 关闭Connection  
	            con.close();   
			}
			car = loginBean.getcar();
			car.clear();
			car.remove(good);//清空暂存订单的列表
		}
		catch (Exception exp){
			System.out.println(exp);
			out.println("<script language = javascript>alert('借车不成功，请重新操作!');");
			out.println("location.href='byPageShow.jsp'</script>");
		}
	}
	public void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		// TODO Auto-generated method stub
		doPost(req, resp);
	}
}
